package com.hc.hc_bot_kit

import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import com.google.gson.Gson
import com.robint.RosController
import com.robint.bean.ExecuteTaskErrorInfo
import com.robint.bean.RosConfig
import com.robint.elevator.api.NavHandlerEventStateListener
import com.robint.elevator.entity.ElevatorInFeedback
import com.robint.http.DataResult
import com.robint.http.NetState
import com.robint.ros.bean.BatteryDataBean
import com.robint.ros.bean.DockStatusBean
import com.robint.ros.bean.MapInfoBean
import com.robint.ros.bean.NavigationStatusBean
import com.robint.ros.bean.base.BaseRosBean
import com.robint.ros.listen.inf.DefaultRosStateListener
import com.robint.ros.listen.inf.RosStateListener
import com.robint.task.handler.NavTaskHandlerEvent
import com.robint.utils.Consumer
import com.robint.utils.IActionCallBack
import java.util.Timer
import java.util.TimerTask

class RobotManager {
    private val TAG: String =
        "RobotManager"

    var navigationLisenter: NavigationLisenter? = null

    private val mainHandler: Handler =
        object :
            Handler(Looper.getMainLooper()) {
            override fun handleMessage(
                msg: Message
            ) {
                super.handleMessage(msg)
                when (msg.what) {

                }
            }
        }

    companion object {
        var mRobotManager: RobotManager = RobotManager()

        fun getInstance(): RobotManager {
            if (mRobotManager == null) {
                mRobotManager =
                    RobotManager()
            }
            return mRobotManager
        }
    }

    fun setOnNavigationLisenter(navigationLisenter: NavigationLisenter?) {
        this.navigationLisenter = navigationLisenter
    }

    //初始化后再调用此方法。每个APP都应该检查ROS是否已经启动，确认启动了再做相应的逻辑
    //Please call this method after initialization. Each APP should check whether ROS is ready, confirm that it is started, and then do the corresponding logic
    fun checkRosReady(callback: Consumer<Boolean?>) {
        //The first way： use getBatteryData check ready

        RosController.getInstance()
            .getBatteryData(
                DataResult<BaseRosBean<BatteryDataBean?>> { ros: BaseRosBean<BatteryDataBean?>, net: NetState ->
                    if (net.isSuccess && ros.getData() != null) {
                        Log.e(
                            TAG, "getBatteryData: if"
                        )
                        callback.accept(true)

                    } else {
                        Timer().schedule(object : TimerTask() {
                            override fun run() {
                                Log.e(
                                    TAG,
                                    "getBatteryData: else"
                                )
                                checkRosReady(
                                    callback
                                )
                            }
                        }, 400)
                    }
                })

        //Another way：use sdk check ready
        val rosIsReady =
            RosController.getInstance()
                .rosIsReady()
    }


    //请只初始化一次
    //Please only initialize once
    fun initSdk(ip: String?, context: Context) {
//        initFields()
        //monitor ros init state
        RosController.getInstance()
            .setRosReadyListener {
                Log.e(
                    TAG,"ros is ready")
            }
        RosController.getInstance()
            .initRos(
                context,
                RosConfig()
                    .setShowLog(
                        true
                    )
                    .setIp(ip) // Do you need to connect to the WiFi of the elevator to get on the elevator? If you connect to WiFi, it will be more efficient to use the LAN. true: requires the APP to have system permissions
                    //上电梯是否需要连接电梯的WiFi,如果连接WiFi，会走局域网效率更高。true：需要APP有系统权限
                    .setUseLiftWifi(
                        false
                    ) //default is true,Set to false if the robot needs to take the elevator
                    //如果要上电梯请设置为false
                    .setCustomElevatorMqttServer(
                        true
                    ) //Set the operating environment where the elevator equipment is located, the default is release
                    //设置梯控所在的运行环境,默认release
                    .setEnvironment(
                        RosConfig.ENVIRONMENT_RELEASE
                    )
            )

        //监听底盘的状态变化 具体更多参考文档README.md
        //Monitor the state changes of the chassis for more specific reference documents README.md
        RosController.getInstance().rosStatusService.unregisterListener(
            mRosMqttEventListener
        )
        RosController.getInstance().rosStatusService.registerListener(
            mRosMqttEventListener,
            RosStateListener.LISTEN_ALL
        )

        //导航和上电梯过程中的相关事件
        //Related events during navigation and elevator ride
        RosController.getInstance().navEventStateListener =
            navHandlerEventStateListener
    }

    //for ui
    private fun appendText(
        uiMessage: String
    ) {
        Log.d(
            TAG,
            "appendText: $uiMessage"
        )
//        EventBus.getDefault()
//            .post(
//                UIMessageEvent(
//                    uiMessage
//                )
//            )
    }


    private var navHandlerEventStateListener =
        object :
            NavHandlerEventStateListener() {
            override fun navTaskEvent(
                navTaskHandlerEvent: NavTaskHandlerEvent
            ) {


                mainHandler.post {
                    //event 只有部分示例 更多请看文档README.md
                    //To view more events, please refer to the documentation
                    Log.e(
                        TAG,
                        "navTaskEvent:" + navTaskHandlerEvent.event
                    )

                    when (navTaskHandlerEvent.event) {
                        NavTaskHandlerEvent.EVENT_NAV_START -> {
                            appendText("navigation start")
                            navigationLisenter?.stateChange(NavigationState.STATE_START)
                        }

                        NavTaskHandlerEvent.EVENT_UPDATE_CURRENT_MAP -> {
                            navigationLisenter?.stateChange(NavigationState.STATE_TRACK_UPDATE)
                        }

                        NavTaskHandlerEvent.EVENT_SINGLE_NAV_END ->                             //One of the navigation ends, not necessarily reaching the target point
                            //去目标点其中一个导航结束，不一定到达目标点

                            //Please use “onNavigationStateChange-->isReached” for the judgment logic of reaching the target point
                            //到达目标点的判断逻辑请用“onNavigationStateChange-->isReached”
                            appendText(
                                "One of the navigation ends"
                            )

                        NavTaskHandlerEvent.EVENT_EXECUTE_TASK_ERROR -> {
                            appendText(
                                "exception occurred，task need stop"
                            )
//                        EventBus.getDefault()
//                            .post(
//                                TaskEvent(
//                                    TaskEvent.EVENT_ERROR
//                                )
//                            )
                            val executeTaskErrorInfo: ExecuteTaskErrorInfo =
                                Gson().fromJson(
                                    navTaskHandlerEvent.data,
                                    ExecuteTaskErrorInfo::class.java
                                )
                            Log.e(
                                TAG,
                                "onNavigationStateChange:Error-" + executeTaskErrorInfo.errorType
                            )

                        }
                    }
                }
            }

            override fun reserveElevator(
                p0: String?,
                p1: IActionCallBack?
            ) {
            }

            override fun freeServerElevator(
                p0: String?,
                p1: IActionCallBack?
            ) {
            }

            override fun dispatchMoveInFeeback(
                p0: ElevatorInFeedback?
            ) {
            }

            override fun pubEleMessageToServer(
                p0: String?,
                p1: Int,
                p2: String?,
                p3: IActionCallBack?
            ) {
            }

            override fun pubEleMessageToServer(
                p0: String?,
                p1: Int,
                p2: String?
            ) {
            }
        }


    //机器人MQTT状态变化的通知，只示例部分事件，更过参考说明文档 README.md
    //Notification of robot MQTT state changes，Only some events are shown, for more details, please refer to the documentation README.md
    private var mRosMqttEventListener: DefaultRosStateListener =
        object :
            DefaultRosStateListener() {
            override fun onBatteryDataChange(
                rosBean: BatteryDataBean,
                flag: Int
            ) {
                super.onBatteryDataChange(
                    rosBean,
                    flag
                )
                Log.e(
                    TAG,"onBatteryDataChange:" + rosBean.isIs_charging)
                if (rosBean.isIs_charging) {
                    //机器人是充电状态
                    //Robot is charging
                }
            }

            override fun onDock(
                dockStatusBean: DockStatusBean
            ) {
                super.onDock(
                    dockStatusBean
                )

                //Navigating to the charging pile is quite special, and the judgment of arrival is as follows:
                if (dockStatusBean.isStop) {
                    if (dockStatusBean.finished) {
                        //Arrive at the charging pile
                        Log.e(
                            TAG,
                            "onDock:抵达充电桩"
                        )

//                        EventBus.getDefault()
//                            .post(
//                                NavigationEvent(
//                                    NavigationEvent.NAV_REACHED
//                                )
//                            )
                    } else {
                        Log.e(
                            TAG,
                            "onDock:抵达充电桩错误"
                        )
//                        EventBus.getDefault().post(NavigationEvent(NavigationEvent.NAV_FAILURE))
                    }
                }
            }

            override fun onCurrentMapChange(
                rosBean: MapInfoBean
            ) {
                super.onCurrentMapChange(
                    rosBean
                )
            }

            override fun onNavigationStateChange(
                data: NavigationStatusBean
            ) {
                super.onNavigationStateChange(
                    data
                )
                //机器人导航状态变化


                if (data.isGateEnterPoint || data.isGateInPoint) {
                    Log.e(
                        TAG,
                        "onNavigationStateChange:特殊任务：进闸机"
                    )
                } else if (data.isGateExitPoint || data.isGateOutPoint) {
                    Log.e(
                        TAG,
                        "onNavigationStateChange:特殊任务：出闸机"
                    )
                } else if (data.isolatedWaitPoint()) {
                    //特殊任务,请忽略
                    Log.e(
                        TAG,
                        "onNavigationStateChange:特殊任务"
                    )
                } else {
                    /****** !!!!!!!!  Very important  !!!!!!!!   */
                    /****** !!!!!!!!  Very important  !!!!!!!!   */

                    if (data.isRunning) {
                        Log.e(
                            TAG,
                            "onNavigationStateChange:Runing"
                        )
                    } else if (data.isPause) {
                        Log.e(
                            TAG,
                            "onNavigationStateChange:isPause"
                        )
                    } else if (data.isStop) {
                        //导航结束：isReached()==true就是成功到达目标点，否则就是任务异常终止
                        if (data.isReached) {
                            navigationLisenter?.stateChange(NavigationState.STATE_REACHED)
                            Log.e(
                                TAG,
                                "onNavigationStateChange:导航到达目标点位"
                            )
                            //导航到达目标点位
//                            EventBus.getDefault().post(NavigationEvent(NavigationEvent.NAV_REACHED))
                        } else {
                            navigationLisenter?.stateChange(NavigationState.STATE_FAILURE)
                            Log.e(
                                TAG,
                                "onNavigationStateChange:导航失败"
                            )
//                            EventBus.getDefault().post(NavigationEvent(NavigationEvent.NAV_FAILURE))
                        }
                    }
                }
            }
            /****
             *
             * 更多方法请参考说明文档README.md
             * For more methods, please refer to the documentation README.md
             *
             */
            /****
             *
             * 更多方法请参考说明文档README.md
             * For more methods, please refer to the documentation README.md
             *
             */
            //onEstopChange
            //onTaskChange
            //onRobotPose
            //onEstopChange
            //......
        }
}